package cn.openea.perpartner.meily.web.service.logistics.businessModule;

import cn.openea.perpartner.common.core.exception.ServiceException;
import cn.openea.perpartner.common.core.utils.DateUtils;
import cn.openea.perpartner.common.core.utils.StringUtils;
import cn.openea.perpartner.meily.constant.CommonConstants;
import cn.openea.perpartner.meily.constant.enums.ExpressCompany;
import cn.openea.perpartner.meily.constant.enums.ExpressStatus;
import cn.openea.perpartner.meily.constant.enums.LogisticsModule;
import cn.openea.perpartner.meily.web.entity.LogisticsInfo;
import cn.openea.perpartner.meily.web.entity.dto.TrialEvaluationSubDTO;
import cn.openea.perpartner.meily.web.entity.vo.ProductDeliveryVo;
import cn.openea.perpartner.meily.web.service.ILogisticsInfoService;
import cn.openea.perpartner.meily.web.service.ITrialEvaluationService;
import cn.openea.perpartner.meily.web.service.logistics.LogisticsQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Optional;

/**
 * @author ysk
 * @version 1.0.1
 * @Description 测评物流查询
 * @createTime 2023年05月10日 15:16:00
 */
@Slf4j
@Service(value = LogisticsModuleService.EVALUATION_LOGISTICS_QUERY)
public class EvaluationLogisticsModuleService extends LogisticsModelAbstractService {

    @Resource
    private ITrialEvaluationService trialEvaluationService;
    @Resource
    private LogisticsQuery logisticsQuery;
    @Resource
    private ILogisticsInfoService logisticsInfoService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LogisticsInfo findByModuleId(String moduleId) {
        TrialEvaluationSubDTO evaluationSubDTO = Optional.ofNullable(trialEvaluationService.getEvaluationSubDetailById(moduleId))
                .orElseThrow(() -> new ServiceException("测评数据不存在"));
        LogisticsInfo logisticsInfo = logisticsQuery.findByModuleAndModuleId(LogisticsModule.EVALUATION, moduleId);
        if (logisticsInfo == null && "已发货".equals(evaluationSubDTO.getOrderStatus())) {
            // 物流信息还没追踪，去查实时物流接口
            synchLogistics(evaluationSubDTO,
                    ExpressCompany.getByCode(evaluationSubDTO.getExpressCompanyCode()),
                    evaluationSubDTO.getCourierNumber(),
                    evaluationSubDTO.getConsigneePhoneNum(),
                    null
            );
            return logisticsQuery.findByModuleAndModuleId(LogisticsModule.EVALUATION, moduleId);
        }
        return logisticsInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void logisticsChange(ExpressCompany expressCompany, String id, String courierNumber) {
        TrialEvaluationSubDTO evaluationSubDTO = Optional.ofNullable(trialEvaluationService.getEvaluationSubDetailById(id))
                .orElseThrow(() -> new ServiceException("测评数据不存在"));
        String orderStatus = evaluationSubDTO.getOrderStatus();
        String logisticsId = "";
        if ("已发货".equals(orderStatus)) {
            // 改物流操作
            LogisticsInfo logisticsInfo = this.findByModuleId(id);
            if (logisticsInfo != null && ExpressStatus.isInTransport(logisticsInfo.getStatus())) {
                throw new ServiceException("测评样品已经在运输中，不可更改物流");
            }
            if (logisticsInfo != null) {
                logisticsId = logisticsInfo.getId();
            }
        }
        evaluationSubDTO.setCourierNumber(courierNumber);
        evaluationSubDTO.setCourierName(expressCompany != null ? expressCompany.getName() : "");
        evaluationSubDTO.setDeliveryGoodsTime(DateUtils.getNow());
        // 先同步物信息
        expressCompany = synchLogistics(evaluationSubDTO,
                expressCompany,
                courierNumber,
                evaluationSubDTO.getConsigneePhoneNum(),
                logisticsId);
        // 走到这一步，物流公司不可能为空
        trialEvaluationService.productDelivery(ProductDeliveryVo.builder()
                .expressCompany(expressCompany)
                .docUnid(evaluationSubDTO.getDocUnid())
                .orderStatus(orderStatus)
                .courierNumber(courierNumber)
                .build());
    }

    @Override
    public LogisticsInfo findRealTimeLogistics(String moduleId) {
        TrialEvaluationSubDTO evaluationSubDTO = Optional.ofNullable(trialEvaluationService.getEvaluationSubDetailById(moduleId))
                .orElseThrow(() -> new ServiceException("测评数据不存在"));
        LogisticsInfo logisticsInfo = checkEventuallyLogistics(LogisticsModule.EVALUATION, moduleId);
        if (logisticsInfo != null && logisticsInfo.isSing()) {
            // 这是最终的物流信息了，不可能还有更新
            return logisticsInfo;
        }
        // 同步物流到自己表里面
        synchLogistics(evaluationSubDTO,
                ExpressCompany.getByCode(evaluationSubDTO.getExpressCompanyCode()),
                evaluationSubDTO.getCourierNumber(),
                evaluationSubDTO.getConsigneePhoneNum(),
                logisticsInfo != null ? logisticsInfo.getId() : null
        );
        // 返回最新的数据
        return logisticsQuery.findByModuleAndModuleId(LogisticsModule.EVALUATION, moduleId);
    }

    @Override
    public void businessStatusSync(LogisticsInfo logisticsInfo) {
        if (StringUtils.isBlank(logisticsInfo.getId()) || StringUtils.isBlank(logisticsInfo.getModuleId())) {
            throw new ServiceException("物流Id和业务模块Id不能为空");
        }
        TrialEvaluationSubDTO evaluationSubDTO = Optional.ofNullable(trialEvaluationService.getEvaluationSubDetailById(logisticsInfo.getModuleId()))
                .orElseThrow(() -> new ServiceException("测评数据不存在"));
        if ("已完成".equals(evaluationSubDTO.getOrderStatus())) {
            // 业务完成
            logisticsInfoService.updateBusinessStatus(logisticsInfo.getId(), CommonConstants.LOGISTICS.BUSINESS_FINISH);
        }
    }
}
